package com.xzx.framework.config;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 定时任务 redis锁注解切面
 */
@Aspect
@Component
public class AspectJob {

    public static Logger log= Logger.getLogger(AspectJob.class);

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    //拦截注解方法


    //拦截注解类
    @Pointcut("@within(com.*.job.config.AnnotationJob)")
    public void redisKeyMethod(){};

    //拦截注解方法
    @Pointcut("@annotation(com.*.job.config.AnnotationJob)")
    public void redisKeyClass(){};

    @Around("redisKeyClass()")
    public Object redisKeyClassBefore(ProceedingJoinPoint joinPoint) throws Throwable {
        return this.redisKeyAround(joinPoint);
    }


    @Around("redisKeyMethod()")
    public Object redisKeyAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("定时任务分布式锁切面========start");
        //拦截的实体类
        Object target = joinPoint.getTarget();
        //拦截的方法名称
        String methodName = joinPoint.getSignature().getName();
        String key=target.getClass().getName()+"."+methodName;
        //获取注解
        AnnotationJob aj= ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(AnnotationJob.class);
        if(aj==null)
            aj=target.getClass().getAnnotation(AnnotationJob.class);
        if(aj==null){
            log.error("定时任务获取切面注解错误！"+key);
            log.warn("定时任务没有分布式锁注解："+key);
            return null;
        }
        log.info("redis加锁key:"+key+",加锁时间="+aj.value());
        Object obj=null;
        if(stringRedisTemplate.opsForValue().setIfAbsent(key,key)){
            log.info("加锁成功："+key);
            stringRedisTemplate.expire(key,aj.value(), TimeUnit.SECONDS);
            try {
                obj=joinPoint.proceed();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                log.info("释放锁："+key);
                stringRedisTemplate.delete(key);
            }
        }
        else{
            log.warn("redis加锁失败"+key+",加锁时间="+aj.value());
            return  null;
        }
        return obj;

    }







}
